/**
 * Date:2019年9月29日 下午3:10:10
 * Copyright (c) 2019, www.bwbroad.com All Rights Reserved
 */

package com.app.common.core;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

/**
 * Description: 统一异常处理 <br/>
 * 所有的系统业务应该抛出AppException Date:2019年9月29日 下午3:10:10 <br/>
 * https://mp.weixin.qq.com/s/lovF-6oWzrUFf-oJDJI2UQ
 * 
 * @author xuejianxin
 */
@ControllerAdvice
public class GlobalExceptionHandler {
	private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

	@ExceptionHandler(value = Exception.class)
	@ResponseBody
	public Object logicExceptionHandler(HttpServletRequest request, Exception e, HttpServletResponse response) {

		// 系统级异常，错误码固定为-1，提示语固定为系统繁忙，请稍后再试
		AppResponse result = new AppResponse();
		// 如果是业务逻辑异常，返回具体的错误码与提示信息
		if (e instanceof AppException) {
			AppException appException = (AppException) e;
			result.error(appException.getCode(), appException.getMessage());
		} else {
			int len = e.getMessage().length();
			len = len <= 150 ? len : 150;
			result.error(AppException.DEFAULT_EXCPTION_CODE, e.getMessage().substring(0, len));
		}
		// 对系统级异常进行日志记录
		logger.error("系统异常:" + e.getMessage(), e);
		return result;
	}

	// 参考文章
	// https://mp.weixin.qq.com/s/kZoCNmEzKdCbbV6C5WVHfg
	// 参数校验 @Validated https://mp.weixin.qq.com/s/kZoCNmEzKdCbbV6C5WVHfg
	// https://mp.weixin.qq.com/s/8vXwepbxcbBEYo2sW-rUnw
	@ExceptionHandler({ MethodArgumentNotValidException.class })
	@ResponseStatus(HttpStatus.OK)
	@ResponseBody
	public AppResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
		BindingResult bindingResult = ex.getBindingResult();
		StringBuilder sb = new StringBuilder("校验失败:");
		for (FieldError fieldError : bindingResult.getFieldErrors()) {
			sb./* append(fieldError.getField()).append("："). */append(fieldError.getDefaultMessage()).append(", ");
		}
		String msg = sb.toString();
		AppResponse aResponse = new AppResponse();
		aResponse.error("-2", msg);
		return aResponse;
	}

}
